package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;

@Service
@PropertySource("classpath:/image.properties")//动态导入pro配置文件
public class FileServiceImpl implements FileService{
    //最优做法：应该使用配置文件动态的属性赋值！！！
    @Value("${file.localDirPath}")
    private String localDirPath ;//真实路径
    @Value("${file.preURLPath}")
    private String preURLPath ;//虚拟路径

    /*
     * 1.验证上传的文件是图片，   jpg/png/gif   采用正则的方式校验
     * 2.防止恶意程序攻击，验证图片是否有宽度和高度
     * 3.文件分目录存储   例如：/2021/11/11
     *                  例如2：hash码，8位hash
     * 数据hash时，因为是算法，可能造成数据分配不均!!
     * 4.防止文件重名，修改文件名称 UUID
     *
     * */
    @Override
    public ImageVO upload(MultipartFile file) {
        //1.校验图片类型是否正确，正则表达式
        //1.1获取文件名称
        String fileName = file.getOriginalFilename();
        //1.3将名称全部小写
        fileName = fileName.toLowerCase();
        //1.2正则校验
        //matches:这个方法主要是返回是否匹配指定的字符串，如果匹配则为true,否则为false;
        if(!fileName.matches("^.+\\.(jpg|png|gif)$")){
            //如果文件不是图片，则返回null
            return null;
        }
        //2校验文件是否为恶意程序
        //2.1将文件转化为图片对象,通过图片对象,获取宽度和高度
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            int height = bufferedImage.getHeight();
            int width = bufferedImage.getWidth();
            if (height == 0 || width == 0){
                return null;
            }

            //3.实现分目录存储
            //3.1按照时间将分配目录   /yyyy/MM/dd
            String dataDirPath = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
            //3.2"D:/images/yyyy/MM/dd/"
            String localDir = localDirPath + dataDirPath;
            File dirFile = new File(localDir);
            if (!dirFile.exists()){//如果目录不存在，则创建目录
                dirFile.mkdirs();
            }

            //4.防止文件重名，生成UUID
            String uuid = UUID.randomUUID().toString()
                    .replace("-", "");
            int index = fileName.lastIndexOf(".");
            //获取后缀
            /*substring:  substring()的作用就是截取父字符串的某一部分
            public String substring(int beginIndex, int endIndex)
            第一个参数int为开始的索引，对应String数字中的开始位置，
            第二个参数是截止的索引位置，对应String中的结束位置
            1、取得的字符串长度为：endIndex - beginIndex;
            2、从beginIndex开始取，到endIndex结束，从0开始数，其中不包括endIndex位置的字符
            */
            String fileType = fileName.substring(index);
            String realFileName = uuid + fileType;

            //5.实现文件上传
            //5.1拼接文件的全路径
            String localFilePath = localDir + realFileName;
            //5.2完成文件上传
            file.transferTo(new File(localFilePath));
            /*
            * 不带磁盘路径的本地存储路径，虚拟动态目录
            *
            * */
            String virtualPath = dataDirPath + realFileName;
            //图片访问网络地址："http://image.jt.com/2021/07/13/85a.jpg"
            //真实磁盘地址："D:/images/2021/07/13/85a.jpg"
            String urlPath = preURLPath + virtualPath;
            ImageVO imageVO =  new ImageVO(virtualPath,urlPath,realFileName);
            System.out.println(imageVO);
            return imageVO;



        } catch (IOException e) {
            e.printStackTrace();
            //终止程序
            return null;
        }



    }

    //1.准备文件的全路径
    //2.执行删除操作
    @Override
    public void deleteFile(String virtualPath) {
        String path = localDirPath + virtualPath;
        File file = new File(path);
        //实现文件删除操作
        file.delete();
    }










    /*文件上传入门案例
    *步骤：
    *   1.准备文件上传目录
    *   2.获取文件上传名称
    *   3.拼接文件路径
    *   4.实现文件上传
    *关于异常处理原则：
    *       将检查异常转化为运行时异常
    *  */
    /*@Override
    public void upload1(MultipartFile file) {
        String filePath = "D:/images/";
        File fileDir = new File(filePath);
        //判断目录是否存在
        if (!fileDir.exists()){
            //fileDir.mkdir();//创建一级目录
            fileDir.mkdirs(); //创建多级目录
        }
        //获取文件名
        String fileName = file.getOriginalFilename();
        //文件上传目录路径
        String path = filePath + fileName;
        //实现文件上传
        try {
            file.transferTo(new File(path));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException();

        }


    }*/
















}
